﻿/****************************************************************************************************
	Copyright (C) 2010 RapidWebDev Organization (http://rapidwebdev.org)
	Author: Eunge, Legal Name: Jian Liu, Email: eunge.liu@RapidWebDev.org

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ****************************************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using BaoJianSoft.Common;
using BaoJianSoft.ExtensionModel.Properties;

namespace BaoJianSoft.ExtensionModel
{

    /// <summary>
    /// DataTime field metadata
    /// </summary>
    public partial class DateTimeFieldMetadata : IFieldMetadata
    {
        /// <summary>
        /// Gets the type.
        /// </summary>
        /// <value>The type.</value>
        [XmlIgnore]
		public FieldType Type { get { return FieldType.DateTime; } }

        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        /// <value>The description.</value>
        [XmlIgnore]
        public string Description { get; set; }

		/// <summary>
		/// True indicates the field is inherited from parent object metadata.
		/// </summary>
		[XmlIgnore]
		public bool Inherited { get; set; }


        /// <summary>
        /// Validate this field.
        /// </summary>
        /// <param name="value">Value of field</param>
        /// <exception cref="InvalidFieldValueException">This extension field's value is invalid</exception>
        public void Validate(IFieldValue value)
        {
            if (value == null)
            {
                if (this.IsRequired)
                    throw new InvalidFieldValueException(string.Format(Resources.FieldValueCannotBeNull, this.Name));
            }
            else
            {
                DateTime argumentDateTime = (DateTime)value.Value;
                if (this.MaxValue != null)
                {
                    DateTime maxDateTime = GetDateTimeValue(this.MaxValue);
                    if (argumentDateTime > maxDateTime)
                        throw new InvalidFieldValueException(string.Format(Resources.FieldValueGreaterThanTheMaximal, this.Name, maxDateTime));
                }

                if (this.MinValue != null)
                {
                    DateTime minDateTime = GetDateTimeValue(this.MinValue);
                    if (argumentDateTime < minDateTime)
						throw new InvalidFieldValueException(string.Format(Resources.FieldValueLessThanTheMinimal, this.Name, minDateTime));
                }
            }
        }

        /// <summary>
        /// Get default field value
        /// </summary>
        /// <returns>if no default value, return null</returns>
        public IFieldValue GetDefaultValue()
        {
            if (this.DefaultValue == null) return null;
            return GetDateTimeValue(this.DefaultValue).FieldValue();
        }

        private static DateTime GetDateTimeValue(DateTimeValue dateTimeValue)
        {
            switch (dateTimeValue.DateTimeValueType)
            {
                case DateTimeValueTypes.Now:
                    return DateTime.Now;
                case DateTimeValueTypes.FirstDayOfThisYear:
                    return new DateTime(DateTime.Now.Year, 1, 1);
                case DateTimeValueTypes.FirstDayOfThisMonth:
                    return new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                case DateTimeValueTypes.FirstDayOfThisWeek:
                    int dayOfWeek;
                    if (DateTime.Now.DayOfWeek == DayOfWeek.Sunday) dayOfWeek = 7;
                    else dayOfWeek = (int)DateTime.Now.DayOfWeek;

                    return DateTime.Now.AddDays(DateTime.Now.Day - dayOfWeek + 1);
                default:
                    if (dateTimeValue.ValueSpecified) return dateTimeValue.Value;
                    throw new ArgumentException(Resources.NotSpecifiedDate, "dateTimeValue");
            }
        }

		#region ICloneable Members

		object ICloneable.Clone()
		{
			return new DateTimeFieldMetadata
			{
				Description = this.Description,
				Inherited = this.Inherited,
				IsRequired = this.IsRequired,
				Name = this.Name,
				DefaultValue = this.DefaultValue,
				MaxValue = this.MaxValue,
				MinValue = this.MinValue,
				Ordinal = this.Ordinal
			};
		}

		#endregion
    }
}
